#include "network.h"
#include "conn_tab.h"

static attack_t underAttack(rawPacket_t* packet, char *params){
	//XMAS packet
	if(packet->protocol == PROT_TCP){
		//params are tcp params
		tcpHeaderParams_t *tcpParams = (tcpHeaderParams_t *)params;
		if(tcpParams->syn && tcpParams->ack  && tcpParams->fin  && tcpParams->rst && tcpParams->urg  && tcpParams->ece  && tcpParams->cwr  && tcpParams->psh){
			return ATTACK_XMAS;
		}
	}
	return ATTACK_NONE;
}

static void makeRawPacket(struct sk_buff *skb, rawPacket_t *packet, tcpHeaderParams_t *params){
	struct iphdr *iph; 
	struct tcphdr *tcph;
	struct udphdr *udph;	
	unsigned short sPort = 0, dPort = 0;	
	char protocol = 0;
	char *pointer;
	pointer = (char *)skb;
	iph = (struct iphdr *) skb_header_pointer(skb, 0, 0, NULL); // get IP header
	//Version
	packet->version = iph->version;	
	pointer += sizeof(struct iphdr);
	//Protocol and IPs
	packet->protocol = iph->protocol;
	packet->source_ip = ntohl(iph->saddr);
	packet->dest_ip = ntohl(iph->daddr);
	//Ports
	if(iph->protocol == PROT_TCP){ //TCP
		tcph = (struct tcphdr*)skb_header_pointer (skb,sizeof(struct iphdr), 0, NULL);
		//tcph = (struct tcphdr *)(skb->data + (iph->ihl << 2));
		params->syn = tcph->syn;
		params->ack = tcph->ack;
		params->fin = tcph->fin;
		params->rst = tcph->rst;
		params->urg = tcph->urg;
		params->ece = tcph->ece;
		params->cwr = tcph->cwr;
		params->psh = tcph->psh;
		sPort = ntohs(tcph->source);
		dPort = ntohs(tcph->dest);
		protocol = PROT_TCP;
		pointer += sizeof(struct tcphdr);	 
	}else if(iph->protocol == PROT_UDP){ //UDP
		udph = (struct udphdr*) (skb + sizeof(struct iphdr));
		sPort = ntohs(udph->source);
		dPort = ntohs(udph->dest);	
		protocol = PROT_UDP;
		pointer += sizeof(struct udphdr);	
	}else if(iph->protocol == PROT_ICMP){ //ICMP
		protocol = PROT_ICMP;
		pointer += sizeof(struct icmphdr);
	}
	packet->protocol = protocol;
	packet->source_port = sPort;
	packet->dest_port = dPort;
}


//All ips are in computer endian
static __u32 applyMaskToIP(__u32 ip, __u8 mask){
	// zero out right bits
	__u32 result = ip;
	__u32 shiftBits = MAX_BITS_MASK - mask;
	int i;
	for(i=0;i<shiftBits;++i){
		result >>= 1;
	}
	for(i=0;i<shiftBits;++i){
		result <<= 1;
	}
	return result;
}
